package com.gzsxy.esjy.service.auth.controller.api;


import com.alibaba.fastjson.JSON;
import com.gzsxy.esjy.common.base.exception.impl.CustomAssert;
import com.gzsxy.esjy.common.base.result.ResultCodeEnum;
import com.gzsxy.esjy.common.base.util.JwtInfo;
import com.gzsxy.esjy.common.base.util.JwtUtils;
import com.gzsxy.esjy.common.base.util.RequestUtil;
import com.gzsxy.esjy.redis.extend.RedisService;
import com.gzsxy.esjy.service.auth.shiro.config.CurrentUserUtil;
import com.gzsxy.esjy.service.auth.shiro.config.MyAuthenticationToken;
import com.gzsxy.esjy.service.base.DictionaryConstants;
import com.gzsxy.esjy.service.base.dto.request.UserLoginRequest;
import com.gzsxy.esjy.service.base.dto.response.DefaultResponse;
import com.gzsxy.esjy.service.base.dto.response.UserRsp;
import com.gzsxy.esjy.service.base.handler.GuliEception;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @author xiaolong
 * @version 1.0
 * @description: 权限认证
 * @date 2022/2/7 15:38
 */
@CrossOrigin  //解决跨域
@RefreshScope    //动态刷新配置文件-外部配置文件
@RestController
@RequestMapping("/api/auth")
@Api("权限认证")
@Slf4j
public class ApiAuthController {

    @Autowired
    private RedisService redisService;


    @PostMapping("/login")
    @ApiOperation("用户登录")
    public DefaultResponse login(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request){
        //验证账号密码
        Subject subject = SecurityUtils.getSubject();
        MyAuthenticationToken token = new MyAuthenticationToken(userLoginRequest.getSchool(),userLoginRequest.getUserName(), userLoginRequest.getPassword().toCharArray());
        try {
            subject.login(token);
        } catch (UnknownAccountException uae) {
            CustomAssert.notTrue(false, ResultCodeEnum.LOGIN_MOBILE_ERROR.getMessage());
        } catch (IncorrectCredentialsException ice) {
            CustomAssert.notTrue(false, ResultCodeEnum.LOGIN_MOBILE_ERROR.getMessage());
            //账号已被锁定，禁止登录
        } catch (LockedAccountException lae) {
            CustomAssert.notTrue(false, ResultCodeEnum.LOCKED_ACCOUNT_PROHIBITED.getMessage());
        }
        UserRsp user = CurrentUserUtil.getUser();
        //生成jwt令牌
        JwtInfo jwtInfo = new JwtInfo();
        jwtInfo.setId(user.getId());
        jwtInfo.setName(user.getName());
        jwtInfo.setImagePath(user.getImagePath());
        String jwtToken = JwtUtils.getJwtToken(jwtInfo, 1800);
        user.setAccessToken(jwtToken);
//        user.setAccessToken(IdUtil.fastSimpleUUID());
        //设置ip
        user.setIp(RequestUtil.getClientIp(request));
        //登录次数统计
        redisService.incr(DictionaryConstants.LOGIN_NUM,DictionaryConstants.NUMBER_1);
        return DefaultResponse.ok(user);
    }



    @PostMapping("/currentUserInfo")
    @ApiOperation("获取登录用户信息")
    public DefaultResponse currentUserInfo(HttpServletRequest request){
        UserRsp user = CurrentUserUtil.getUser();
        log.info("【获取当前用户信息为】,{}", JSON.toJSONString(user));
        if (ObjectUtils.isEmpty(user)){
            log.info("【微信授权登录-通过jwt获取用户信息】");
            JwtInfo user1 = null;
            try {
                if (request instanceof ShiroHttpServletRequest){
                    String authorization = ((ShiroHttpServletRequest) request).getHeader("Authorization");
                    user1 = JwtUtils.getMemberIdByJwtToken(authorization);
                } else {
                    user1 = JwtUtils.getMemberIdByJwtToken((ServerHttpRequest) request);
                }
                return DefaultResponse.ok(user1);
            } catch (Exception e) {
                log.error("解析用户信息失败:"+e.getMessage());
                throw new GuliEception(ResultCodeEnum.FETCH_USERINFO_ERROR);
            }
        }
        return DefaultResponse.ok(user);
    }


    @GetMapping("/logout")
    @ApiOperation("用户登出")
    public DefaultResponse logout(HttpSession session){
        SecurityUtils.getSubject().logout(); //shrio 的subject退出 自动清掉session
        return DefaultResponse.ok();
    }

}
